package pl.wr.particle.impl.quantum;

import pl.wr.particle.def.matter.elementary.fermions.leptons.IElectron;
import pl.wr.particle.def.quantum.IElectronShell;
import pl.wr.particle.impl.matter.elementary.fermions.leptons.Electron;
import pl.wr.physics.exceptions.QuantumException;
import pl.wr.physics.units.quantum.number.MagneticQuantumNumber;
import pl.wr.physics.units.quantum.number.SpinQuantumNumber;

/**
 * @version 1.0
 * @author wieslaw.rodak
 * 
 */
public class ElectronShell implements IElectronShell {

    protected Shell shell;
    protected SubShell[] subShells;
    private IElectron[] electrons;

    public ElectronShell(Shell shell, int electrons) {
        this.shell = shell;
        addElectrons(electrons);
    }

    @Override
    public Shell getShell() {
        return shell;
    }

    @Override
    public SubShell[] getSubShells() {
        return subShells;
    }

    public void setSubshell(SubShell[] subshells) {
        // if (shell == null) {
        // throw new QuantumException("Brak zdefiniowanej powłoki głównej");
        // }
        // if (shell != null && subshell.getQuantumNumber().getL() <
        // shell.getQuantumNumber().getN()) {
        // this.subshells = subshell;
        // } else {
        // throw new QuantumException("Nieprawidłowa podpowłoka");
        // }
    }

    public IElectron[] getElectrons() {
        return electrons;
    }

    private void addElectrons(int count) {

        switch (shell) {
        case K:
            if (count < 2) { // s
                fill(Shell.K, count);
            } else {
                electrons = new IElectron[2];
                fillFullShell(Shell.K);
            }
            break;
        case L:
            if (count < 8) { // 2+6 sp
                fill(Shell.L, count);
            } else {
                electrons = new IElectron[8];
                fillFullShell(Shell.L);
            }
            break;
        case M:
            if (count < 18) { // 2+6+10 spd
                fill(Shell.M, count);
            } else {
                electrons = new IElectron[18];
                fillFullShell(Shell.M);
            }
            break;
        case N:
            if (count < 32) { // 2+6+10+14 spdf
                fill(Shell.N, count);
            } else {
                electrons = new IElectron[32];
                fillFullShell(Shell.N);
            }
            break;
        case O:
            if (count < 50) { // 2+6+10+14+18 spdfg
                fill(Shell.O, count);
            } else {
                electrons = new IElectron[50];
                fillFullShell(Shell.O);
            }
            break;
        case P:
            if (count < 72) { // 2+6+10+14+18+22 spdfgh
                fill(Shell.P, count);
            } else {
                electrons = new IElectron[72];
                fillFullShell(Shell.P);
            }
            break;
        case Q:
            if (count < 98) { // 2+6+10+14+18+22+26 spdfghi
                fill(Shell.Q, count);
            } else {
                electrons = new IElectron[98];
                fillFullShell(Shell.Q);
            }
            break;

        default:
            throw new QuantumException("Nieprawidłowa powłoka");

        }
    }

    private void fillFullShell(Shell k) {
        System.out.println("full " + k);

        switch (k) {
        case K:
            SubShell[] shellK = { SubShell.s };
            subShells = shellK;
            break;
        case L:
            SubShell[] shellL = { SubShell.s, SubShell.p };
            subShells = shellL;
            break;
        case M:
            SubShell[] shellM = { SubShell.s, SubShell.p, SubShell.d };
            subShells = shellM;
            break;
        case N:
            SubShell[] shellN = { SubShell.s, SubShell.p, SubShell.d, SubShell.f };
            subShells = shellN;
            break;
        case O:
            SubShell[] shellO = { SubShell.s, SubShell.p, SubShell.d, SubShell.f, SubShell.g };
            subShells = shellO;
            break;
        case P:
            SubShell[] shellP = { SubShell.s, SubShell.p, SubShell.d, SubShell.f, SubShell.g, SubShell.h };
            subShells = shellP;
            break;
        case Q:
            SubShell[] shellQ = { SubShell.s, SubShell.p, SubShell.d, SubShell.f, SubShell.g, SubShell.h, SubShell.i };
            subShells = shellQ;
            break;

        default:
            break;
        }

        for (SubShell subshell : subShells) {
            System.out.print(subshell + " ");
        }
        System.out.println("na " + k);

        fillFullSubShell();
    }

    private void fillFullSubShell() {

        for (SubShell subShell : subShells) {

            switch (subShell) {
            case s:
                MagneticQuantumNumber mag = MagneticQuantumNumber.valueOf(0);
                electrons[0] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(), mag,
                        SpinQuantumNumber.ONE_HALF);
                electrons[1] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(), mag,
                        SpinQuantumNumber.MINUS_ONE_HALF);
                break;
            case p:
                for (int m = -1, el = 0; m < 1; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.ONE_HALF);
                }
                for (int m = -1, el = electrons.length / 2; m < 1; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.MINUS_ONE_HALF);
                }
                break;
            case d:
                for (int m = -2, el = 0; m < 2; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.ONE_HALF);
                }
                for (int m = -2, el = electrons.length / 2; m < 1; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.MINUS_ONE_HALF);
                }
                break;
            case f:
                for (int m = -3, el = 0; m < 3; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.ONE_HALF);
                }
                for (int m = -3, el = electrons.length / 3; m < 1; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.MINUS_ONE_HALF);
                }
                break;
            case g:
                for (int m = -4, el = 0; m < 4; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.ONE_HALF);
                }
                for (int m = -4, el = electrons.length / 4; m < 1; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.MINUS_ONE_HALF);
                }
                break;
            case h:
                for (int m = -5, el = 0; m < 5; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.ONE_HALF);
                }
                for (int m = -5, el = electrons.length / 5; m < 1; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.MINUS_ONE_HALF);
                }
                break;
            case i:
                for (int m = -6, el = 0; m < 6; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.ONE_HALF);
                }
                for (int m = -6, el = electrons.length / 6; m < 1; m++, el++) {
                    electrons[el] = new Electron(shell.getQuantumNumber(), subShell.getQuantumNumber(),
                            MagneticQuantumNumber.valueOf(m), SpinQuantumNumber.MINUS_ONE_HALF);
                }
                break;

            default:
                break;
            }
        }
        System.out.println("elektrony: " + electrons);

    }

    private void fill(Shell k, int count) {

        System.out.println("count " + count + " na " + k);

        electrons = new IElectron[count];

        for (int i = 0; i < count; i++) {
            electrons[i] = new Electron();
        }

    }

}
